package isp.apps.example.shoppingcart.action;

import isp.apps.example.shoppingcart.domain.CalculatedShippingOption;
import isp.apps.example.shoppingcart.domain.ShippingCalculator;
import isp.apps.example.shoppingcart.domain.ShippingCalculatorFactory;
import isp.apps.example.shoppingcart.domain.ShippingOption;
import isp.apps.example.shoppingcart.persistence.factory.ItemPersistenceFactory;
import isp.apps.example.shoppingcart.domain.ShoppingCart;
import isp.apps.example.shoppingcart.domain.UsStates;

import isp.apps.example.shoppingcart.persistence.CreditCardDirectory;
import isp.apps.example.shoppingcart.persistence.ShippingOptionsDirectory;

import isp.apps.example.shoppingcart.persistence.factory.CreditCardPersistenceFactory;
import isp.apps.example.shoppingcart.persistence.factory.ShippingOptionsPersistenceFactory;

import java.math.BigDecimal;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

public class CheckoutAction extends ShoppingAction
{
  private List usStates = null;
  private List shippingOptionsList, cartItemList, calculatedShippingOptionsList;
  private ShippingOptionsDirectory sod = ShippingOptionsPersistenceFactory.getShippingOptionsDirectory();
  private ShippingCalculator shippingCalc = ShippingCalculatorFactory.getShippingCalculator();
  private Collection myCollection;
  private CreditCardDirectory ccDir =
    CreditCardPersistenceFactory.getCreditCardDirectory();
  ShoppingCart myCart;

  public CheckoutAction()
  {
  }


  public BigDecimal getTotalPrice()
  {
    BigDecimal ret = getCart().getTotalPrice();
    return ret.setScale(2, BigDecimal.ROUND_HALF_UP);
  }

  public String execute()
  {
    myCart = getCart();
    myCollection = myCart.getCartItems();
    getCartItems();
    if (myCollection.size() < 1)
    {
       addActionError("You must have at least one item in your cart to proceed to checkout");
       return "CartIsEmpty";
    }
    getShippingOptions();

    return SUCCESS;
  }

  public List getCartItems()
  {
    cartItemList = new ArrayList(myCollection.size());
    for (Iterator iter = myCollection.iterator(); iter.hasNext(); )
    {
      cartItemList.add(iter.next());
    }
    return cartItemList;
  }


  public int getCartSize()
  {
    ShoppingCart sc = getCart();
    return sc.getCartDistinctItemCount();
  }


  public void getShippingOptions()
  {
    calculatedShippingOptionsList = new ArrayList();

    List myList = getCartItems();

    //get valid shipping options
    shippingOptionsList = sod.getValidOptions();
    //TODO create calculatedShippingOption OBJECT to 
    //store the ShippingOption & calculated price based
    //on the contents of myCart

    //iterate though valid options and calc the shipping price for this cart
    for (Iterator i = shippingOptionsList.iterator(); i.hasNext(); )
    {
      //call shippiongCalc(myCart, i.hasNext());
      CalculatedShippingOption cso = new CalculatedShippingOption();
      //get shippingOption from ShippingOptions list
      cso.setShippingOption((ShippingOption) i.next());

      //call shippingCalculator to find the price
      //pass the shippingcalc the current shopping cart myCart and the shippingOption
      //cso.setCost(shippingCalc.getShippingCost(cartItemList, cso.getShippingOption()));
      cso.setCost(shippingCalc.getShippingCost(myList, cso.getShippingOption()));
      calculatedShippingOptionsList.add(cso);
    }
  }


  public List getCalculatedShippingOptionsList()
  {
    return calculatedShippingOptionsList;
  }


  public int getShippingOptionListSize()
  {
    return calculatedShippingOptionsList.size();
  }

  public List getValidCreditCardsList()
  {
    return ccDir.getValidCreditCards();
  }
  
  public int getCreditCardsListSize()
  {
    Collection c = getValidCreditCardsList();
    return c.size();
  }

  public List getUsStates()
  {
    if (usStates == null)
       usStates = UsStates.getUsStatesOrderedByName();
    return usStates;
  }

}
